package tools

import (
	"encoding/json"
	"fmt"

	"workflow-gui/internal/database"
	"workflow-gui/internal/protocol"
)

// WorkflowManagementHandler handles workflow management requests
type WorkflowManagementHandler struct {
	db *database.DB
}

// NewWorkflowManagementHandler creates a new workflow management handler
func NewWorkflowManagementHandler(db *database.DB) *WorkflowManagementHandler {
	return &WorkflowManagementHandler{
		db: db,
	}
}

// ListWorkflowsResponse represents the list workflows response
type ListWorkflowsResponse struct {
	Total     int               `json:"total"`
	Page      int               `json:"page"`
	PageSize  int               `json:"pageSize"`
	Workflows []WorkflowSummary `json:"workflows"`
}

// WorkflowSummary represents a workflow summary
type WorkflowSummary struct {
	ChangeID      string `json:"change_id"`
	Name          string `json:"name"`
	Status        string `json:"status"`
	WorkflowStage string `json:"workflow_stage"`
	CreatedAt     string `json:"created_at"`
	UpdatedAt     string `json:"updated_at"`
}

// HandleListWorkflows handles list workflows request
func (h *WorkflowManagementHandler) HandleListWorkflows(args map[string]interface{}) (protocol.ToolResult, error) {
	// Parse parameters
	status := ""
	if s, ok := args["status"].(string); ok {
		status = s
	}

	page := 1
	if p, ok := args["page"].(float64); ok {
		page = int(p)
	}

	pageSize := 10
	if ps, ok := args["pageSize"].(float64); ok {
		pageSize = int(ps)
	}

	// Validate parameters
	if page < 1 {
		page = 1
	}
	if pageSize < 1 || pageSize > 100 {
		pageSize = 10
	}

	// Calculate offset
	offset := (page - 1) * pageSize

	// Build query - join with proposals to get summary as name
	query := `SELECT p.change_id, COALESCE(pr.summary, '') as name, p.status, p.workflow_stage, p.created_at, p.updated_at
	          FROM projects p
	          LEFT JOIN proposals pr ON p.id = pr.project_id`
	args_list := []interface{}{}

	if status != "" {
		query += " WHERE p.status = ?"
		args_list = append(args_list, status)
	}

	query += " ORDER BY p.created_at DESC LIMIT ? OFFSET ?"
	args_list = append(args_list, pageSize, offset)

	// Execute query
	rows, err := h.db.Query(query, args_list...)
	if err != nil {
		return protocol.NewErrorResult(fmt.Sprintf("Failed to query workflows: %v", err)), nil
	}
	defer rows.Close()

	// Parse results
	workflows := []WorkflowSummary{}
	for rows.Next() {
		var w WorkflowSummary
		if err := rows.Scan(&w.ChangeID, &w.Name, &w.Status, &w.WorkflowStage, &w.CreatedAt, &w.UpdatedAt); err != nil {
			return protocol.NewErrorResult(fmt.Sprintf("Failed to scan row: %v", err)), nil
		}
		workflows = append(workflows, w)
	}

	// Get total count
	countQuery := "SELECT COUNT(*) FROM projects"
	countArgs := []interface{}{}
	if status != "" {
		countQuery += " WHERE status = ?"
		countArgs = append(countArgs, status)
	}

	var total int
	if err := h.db.QueryRow(countQuery, countArgs...).Scan(&total); err != nil {
		return protocol.NewErrorResult(fmt.Sprintf("Failed to get total count: %v", err)), nil
	}

	// Build response
	response := ListWorkflowsResponse{
		Total:     total,
		Page:      page,
		PageSize:  pageSize,
		Workflows: workflows,
	}

	// Serialize to JSON
	responseJSON, err := json.Marshal(response)
	if err != nil {
		return protocol.NewErrorResult(fmt.Sprintf("Failed to serialize response: %v", err)), nil
	}

	return protocol.NewSuccessResult(string(responseJSON)), nil
}

// HandleGetWorkflow handles get workflow request
func (h *WorkflowManagementHandler) HandleGetWorkflow(args map[string]interface{}) (protocol.ToolResult, error) {
	// Extract change_id
	changeID, ok := args["change_id"].(string)
	if !ok || changeID == "" {
		return protocol.NewErrorResult("Missing required argument: change_id"), nil
	}

	// Load project from database
	dao := database.NewProjectDAO(h.db)
	project, err := dao.GetByChangeID(changeID)
	if err != nil {
		return protocol.NewErrorResult(fmt.Sprintf("Failed to load project: %v", err)), nil
	}

	// Serialize to JSON
	projectJSON, err := json.Marshal(project)
	if err != nil {
		return protocol.NewErrorResult(fmt.Sprintf("Failed to serialize project: %v", err)), nil
	}

	// Return complete workflow data
	return protocol.NewSuccessResult(string(projectJSON)), nil
}
